home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Free Software Collection: Marty 1
/
FM Towns Marty 1 Free Software Collection.iso
/
tool
/
book
/
src
/
book.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-11
|
53KB
|
1,709 lines
/*
* <<< ひみつのBook >>>
*
* High Speed Text Viewer for FM-TOWNS
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <math.h>
#include <egb.h>
#include <mos.h>
#include <fmc.h>
#include <msdos.cf>
#include <exec.cf>
#include "event.h"
#include "book.h"
#include "file.h"
#include "init.h"
#include "lib.h"
#include "move.h"
#include "keyio.h"
#include "cons.h"
#include "menu.h"
#include "mouse.h"
/* #define DBG_DSP_MOVE_VAL */
#define VOID_FUNC_POINTER ((void(*)())0)
#define JUMP_LINE 50 /* これ以上移動する場合は、再表示する */
#define SPEED 333 /* 自動スクロールのインターバル */
#define DOTS 3 /* 行間隔は 3種類 */
#define LNUM_X (54*8)
#define LNUM_Y 8
#define PITCH1 23
#define BSIZE1 22
#define FNAM_X 12
#define FNAM_Y 5
#define CR_X (FNAM_X+111) /* 書式設定ボタン */
#define CR_Y FNAM_Y
#define SR_X (CR_X+72) /* 文字列検索ボタン */
#define SR_Y FNAM_Y
#define TITLE_Y_MIN 0 /* タイトルラインの開始位置 */
#define TITLE_Y_MAX 31 /* タイトルラインの最大位置 */
#define TITLE_Y_SIZ (TITLE_Y_MAX-TITLE_Y_MIN+1)
#define SND_X 546 /* 読みあげボタン */
#define SND_Y 6
#define FS_X 574 /* ファイル・セレクタへ移動 */
#define FS_Y 2
#define EXIT_X 608 /* 直接終了するボタン */
#define EXIT_Y 2
#define STD_X2 650 /* スクロール・バー部分の基準位置 */
#define STD_Y2 84
#define BSIZE2 20
#define PITCH2 4
#define HUP_X STD_X2 /* 加速 上スクロール・ボタン */
#define HUP_Y STD_Y2
#define HDOWN_X STD_X2 /* 加速 下スクロール・ボタン */
#define HDOWN_Y (STD_Y2+BSIZE2+PITCH2-4)
#define BAR_X STD_X2 /* スクロール・バー */
#define BAR_Y (HDOWN_Y+BSIZE2+PITCH2-4)
#define BAR_SIZ (200)
#define UP_X STD_X2 /* 一定速度 上スクロール・ボタン */
#define UP_Y (BAR_Y+BAR_SIZ+9)
#define DOWN_X STD_X2 /* 一定速度 下スクロール・ボタン */
#define DOWN_Y (UP_Y+BSIZE2+PITCH2-2)
#define S_XMIN 0 /* 猫の手スクロール通用範囲 */
#define S_XSIZ (STD_X2-4-S_XMIN)
#define S_YMIN 32
#define S_YSIZ (MAX_VERTICAL-S_YMIN)
#define RETVAL_EXIT 0 /* mainへの戻り値 */
#define RETVAL_NEXT 1 /* EXITなら直接終了。NEXTならファイルセレクタ */
static dpl_t dots[DOTS] =
{ {16,30,16,0,480}, {18,27,14,2,482}, {20,24,13,4,473} } ;
static dpl_t *dot = dots ; /* 初期値は0 */
static short offset = 0 ; /* テキスト画面のドット単位のズレ */
short auto_move = 0 ; /* 自動スクロールの速度 */
static short auto_move_value = 0 ; /* 自動スクロールのドット数 */
static int vram_ofs = 0 ;
static mevt_t menu_event = MEv_NULL;
static short vol_size = 0 ;
static HEADER *now_file = NULL ;
short can_use_snd = FALSE ; /* 読み上げ機能の使用可不可 */
static short wide = OFF ; /* 幅広画面 */
short max_horizon = MAX_HORIZON ; /* 最大水平位置 */
static char tmp[256] ;
char *msg[MAX_DSP_MSG] ;
char *btn[MAX_BTN_MSG] ;
int writepage = PAGE0 ; /* 書き込みページ */
int page_ofs = 0x00000 ;
char gwork[ EgbWorkSize ] ;
extern void DSP_scr_bar( int init ) ;
extern void dsp_menu( void ) ;
void init_screen( void )
{
EGB_displayPage( gwork, 0, 0 ) ; /* 表示を停止 */
EGB_resolution( gwork, 0,3 ) ;
EGB_resolution( gwork, 1,3 ) ;
wide_screen(wide); /* 横幅は拡大せず */
vertical_screen( get_now_dpl()->lines ) ; /* 縦のライン数を設定 */
dsp_adr_set(vram_ofs + offset);
/* パレットの設定 */
cls( 0, 8 ) ;
EGB_palette( gwork, 0, (char *)&setup.palette ) ;
cls( 1, 0 ) ;
EGB_palette( gwork, 0, (char *)&setup.palette ) ;
EGB_displayPage( gwork, 1, 3 ) ; /* 表示を再開 */
}
#if 1
void dsp_line(int y, char *buf, int bytes)
{
#define TYP_NORMAL '\0'
#define TYP_SPECIAL '\1'
static char str[81];
static char type[81]; /* 一般文字は 0、それ以外は 1 */
auto int left;
auto int i, pos;
auto char *p, *q;
if (bytes < 0)
return;
memset(type, TYP_NORMAL, 80); /* ノーマルで初期化 */
for (q = type, p = str, i = pos = 0;
i < bytes; pos++, buf++, p++, q++, i++)
{
if (*buf < 0x20) /* 制御コード */
{
if (*buf == '\x0D' && *(buf+1) == '\x0A') /* 改行コード */
{
*q = TYP_SPECIAL;
break;
}
else if (*buf == '\t' && setup.tabsiz > 0) /* タブ */
{
left = setup.tabsiz - (pos % setup.tabsiz);
while (pos < LINEMAX && --left > 0)
*p++ = ' ', q++, pos++;
*p = ' ';
}
else if (setup.disp_ctrl) /* 一般制御コード */
{
*p++ = '^';
*q++ = TYP_SPECIAL;
*p = '@' + *buf;
*q = TYP_SPECIAL;
pos++;
}
else
{
*p = *buf;
*q = TYP_SPECIAL;
}
}
else /* その他の文字 */
{
*p = *buf;
}
}
*p = '\0' ;
y = X_OFFSET + ((y * dot->font + dot->ofs + vram_ofs) << 9) & 0x3FFFF;
putstr(y, str, pos, type);
if (buf[0] == '\x0D' && buf[1] == '\x0A' && setup.disp_cr && pos < LINEMAX)
wrtstr("\x1F", PAGE0,y+(pos<<2), _CR_COL,_BAK_COL,16);
if (dot->spc > 0)
vram_part_clear(y+(16<<9)-X_OFFSET, dot->spc);
}
#else
void dsp_line(int y, char *buf, int bytes)
{
static char str[80];
static long col[80];
auto int left;
auto int i, pos;
auto char *p;
if (bytes < 0)
return;
for (p = str, i = pos = 0; i < bytes; pos++, buf++, p++, i++)
{
if (*buf < 0x20) /* 制御コード */
{
if (*buf == '\x0D' && *(buf+1) == '\x0A') /* 改行コード */
{
if (setup.disp_cr) {
col[pos++] = _CR_COL;
*p = '\x1F';
}
break;
}
else if (*buf == '\t' && setup.tabsiz > 0) /* タブ */
{
left = setup.tabsiz - (pos % setup.tabsiz);
while (pos < LINEMAX && --left > 0)
{
col[pos] = _CHR_COL;
*p++ = ' ', pos++;
}
*p = ' ';
col[pos] = _CHR_COL;
}
else if (setup.disp_ctrl) /* 一般制御コード */
{
col[pos] = _CTRL_COL;
*p++ = '^';
*p = '@' + *buf;
pos++;
col[pos] = _CTRL_COL;
}
else
{
*p = *buf;
col[pos] = _CTRL_COL;
}
}
else /* その他の文字 */
{
*p = *buf;
col[pos] = _CHR_COL;
}
}
*p = '\0';
y = X_OFFSET + ((y * dot->font + dot->ofs + vram_ofs) << 9) & 0x3FFFF;
extern void prtstr(char *str, long *col, int y, int col, int pos);
prtstr(str, col, y, _BAK_COL, pos);
if (dot->spc > 0)
vram_part_clear(y+(16<<9)-X_OFFSET, dot->spc);
}
#endif
dpl_t *get_now_dpl( void ) /* 外部ファイルに現在の行間隔を通知する */
{
return dot ;
}
static void dsp_file(int line)
{
HEADER *hd = now_file;
int i, max = dot->max_y;
LINPTR *lp;
if (hd->line_max > dot->max_y && line > (hd->line_max - dot->max_y))
line = hd->line_max - dot->max_y + 1;
hd->line_now = hd->line_num = line;
hd->cur_pos = 0;
if ((line + dot->max_y - 1) > hd->line_max)
{
max = hd->line_max - line;
cls(0, 8);
DSP_writePage(gwork, 1);
}
for (i = 0; i < max; i++)
{
lp = &(base[line/LINEPTRs]->ptr[line%LINEPTRs]) ;
dsp_line( i, lp->buf, lp->bytes ) ;
line++ ;
}
}
static void _dsp_scrn(int line)
{
HEADER *hd = now_file;
int i, last_num, now;
LINPTR *lp;
last_num = hd->line_num;
if ((i = line - hd->line_now) == 0)
return;
else if (abs(i) > JUMP_LINE)
dsp_file(line);
else
{
now = hd->line_now ;
if (i > 0)
{
while (i-- > 0 && now < hd->line_max)
{
now++;
lp = &(base[now/LINEPTRs]->ptr[now%LINEPTRs]);
if (++hd->cur_pos >= dot->max_y)
{
hd->cur_pos--;
vram_ofs = (vram_ofs + dot->font) & 511;
dsp_line(hd->cur_pos, lp->buf, lp->bytes);
}
}
}
else
{
while (i++ < 0 && now > 0)
{
now--;
lp = &(base[now/LINEPTRs]->ptr[now%LINEPTRs]);
if (--hd->cur_pos < 0)
{
hd->cur_pos++;
vram_ofs = (vram_ofs - dot->font ) & 511;
dsp_line(hd->cur_pos, lp->buf, lp->bytes);
}
}
}
hd->line_now = now;
hd->line_num = hd->line_now - hd->cur_pos;
}
if (last_num != hd->line_num)
DSP_scr_bar(FALSE);
}
static void dsp_scrn(int line)
{
_dsp_scrn(line);
offset %= dot->font;
if (auto_move == 0) /* 自動スクロール中でなければ */
dsp_adr_set(vram_ofs + offset);
}
static void snd_scrn( void )
{
HEADER *hd = now_file ;
LINPTR *lp ;
int pos = 1 ;
int now = hd->line_num + 1 ;
int max = now + dot->max_y - 2 ;
int wrtpos = vram_ofs + dot->ofs ;
mos_ptn( MOSCSR_CLOCK ) ; /* 時計 */
if( offset > 4 )
pos++, now++ ;
if( max > hd->line_max - 2 )
max = hd->line_max - 2 ;
while( now < max )
{
lp = &(base[now/LINEPTRs]->ptr[now%LINEPTRs]) ;
if( snd_str( (wrtpos+pos*dot->font)&511, lp->buf, lp->bytes ) == ERR )
break ;
pos++, now++ ;
}
mos_ptn( MOSCSR_FINGER ) ; /* ひと指し指 */
}
static void AUTO_scroll(void)
{
HEADER *hd = now_file;
if (auto_move == 0)
{
EVT_unset_interval(); /* 自動スクロール停止 */
redisp_lnum(); /* 行番号の表示 */
}
else
{
offset += auto_move_value;
if (offset >= dot->font) /* 正方向スクロール */
dsp_scrn(hd->line_now
+ (dot->max_y - hd->cur_pos - 1) + (offset / dot->font));
else if (offset <= -dot->font) /* 逆方向スクロール */
dsp_scrn(hd->line_now + (offset/dot->font) - hd->cur_pos);
/* 末端まで来たら、停止する */
if ((offset > 0 && hd->line_num + dot->max_y-1 >= hd->line_max) ||
(offset < 0 && hd->line_num == 0) || hd->line_max < dot->max_y)
{
auto_move = 0;
offset = 0;
}
dsp_adr_set(vram_ofs + offset);
}
}
/*
* 自動スクロール開始
*/
int set_auto_scroll(int value)
{
auto_move = value;
return (auto_move_value = EVT_set_interval(129, value, AUTO_scroll));
}
/*
* 自動スクロール停止
*/
void unset_auto_scroll(void)
{
auto_move = 0;
EVT_unset_interval();
}
static void SCREEN_clip(REGS evt_t *ep, int x, int y, int sw)
{
static int last_y;
static int repcount = 0;
int value;
HEADER *hd = now_file;
sw = sw; /* 意味なし。ワーニング回避 */
x = x;
switch(ep->now)
{
case Ev_CLIP_MOS:
mos_ptn( MOSCSR_HAND ) ;
ep->now = Ev_REP_MOS ;
MOS_horizon( ep->x1, ep->x2 ) ; /* 移動範囲制限 */
MOS_vertical( ep->y1, ep->y2 ) ;
unset_auto_scroll(); /* 自動スクロール停止 */
last_y = y;
repcount = 0;
case Ev_REP_MOS: /* 猫の手スクロール */
menu_event = MEv_NULL;
if (++repcount < 20)
break;
repcount = 0;
offset += ( last_y - y ) ;
/* 行き過ぎたら、戻す */
if ((offset > 0 && hd->line_num+dot->max_y-1 >= hd->line_max) ||
(offset < 0 && hd->line_num <= 0) || hd->line_max < dot->max_y)
dsp_adr_set(vram_ofs + (offset = 0));
else if (abs(offset) >= dot->font) /* 行スクロール */
{
if (offset > 0) /* 正方向スクロール */
dsp_scrn(hd->line_now +
(dot->max_y - hd->cur_pos-1)+(offset/dot->font));
else /* 逆方向スクロール */
dsp_scrn(hd->line_now + (offset/dot->font) - hd->cur_pos);
}
else /* ドットスクロール */
dsp_adr_set(vram_ofs + offset);
last_y = y;
break;
case Ev_SELECT_MOS: /* 自動スクロール開始 */
if ((value = (last_y - y)) != 0)
{
if (abs(value) > 5)
value *= 4;
set_auto_scroll(value);
}
MOS_horizon( MIN_HORIZON, max_horizon ) ;
MOS_vertical( MIN_VERTICAL, MAX_VERTICAL ) ;
menu_event = MEv_NULL;
ep->now = Ev_ON_MOS ;
case Ev_ON_MOS:
mos_ptn( MOSCSR_FINGER ) ;
break ;
}
}
/* スクロール・バーのクリップ */
static void MOVE_clip( REGS evt_t *ep, int x, int y, int sw )
{
x = x ; /* 意味なし。ワーニングを避けるため */
sw = sw ;
switch( ep->now )
{
case Ev_CLIP_MOS:
mos_ptn( MOSCSR_HAND ) ;
MOS_horizon( ep->x1, ep->x2 ) ;
MOS_vertical( ep->y1, ep->y2 ) ;
ep->now = Ev_REP_MOS ;
case Ev_REP_MOS:
menu_event = MEv_NULL;
if (vol_size > 0)
{
offset = 0;
dsp_adr_set(vram_ofs);
dsp_scrn(((now_file->line_max) * ( y - ep->y1 ) ) / BAR_SIZ);
}
break ;
case Ev_SELECT_MOS:
ep->now = Ev_ON_MOS ;
case Ev_OFF_MOS:
case Ev_MOVE_MOS:
MOS_horizon( MIN_HORIZON, max_horizon ) ;
MOS_vertical( MIN_VERTICAL, MAX_VERTICAL ) ;
menu_event = MEv_NULL;
case Ev_ON_MOS:
mos_ptn( MOSCSR_HAND ) ;
break ;
}
}
/* スクロール・バーの表示 */
static void DSP_scr_bar(int init)
{
static char vol_ptn[(20+7)*(BAR_SIZ+7)];
static int last_pos = -1;
static int bar_siz;
HEADER *hd = now_file;
int bar_pos;
int mx, my;
/* 画面の幅が広くなく、しかも初期化でなければ、無視 */
if (wide == FALSE && init == FALSE)
return;
if (init == TRUE) /* 初期化と再初期化 */
{
if ((bar_siz = BAR_SIZ * (dot->max_y-1) / hd->line_max) >= BAR_SIZ)
bar_siz = BAR_SIZ-1;
vol_size = BAR_SIZ - bar_siz;
bar_pos = hd->line_num * BAR_SIZ / hd->line_max ;
MOS_disp( MOS_OFF ) ; /* 常に消してから描画 */
/* 地の部分を消去して、 */
pbox( BAR_X,BAR_Y,BAR_X+20,BAR_Y+BAR_SIZ+5, WIND_COL,WIND_COL ) ;
/* 中心軸を描く */
pbox( BAR_X+8,BAR_Y+2, BAR_X+12,BAR_Y+BAR_SIZ+3, BOX2_COL,BOX1_COL ) ;
/* 描いた背景を保存する */
DSP_getBlock( BAR_X,BAR_Y+3, 20,BAR_SIZ+3, vol_ptn ) ;
pbox(BAR_X+2,BAR_Y+3+bar_pos, BAR_X+18,BAR_Y+3+bar_pos+bar_siz, 15,15);
}
else
{
/* 移動先を計算し、表示上の差がなければ描画はしない */
if ((bar_pos = hd->line_num * BAR_SIZ / hd->line_max) == last_pos)
return;
/* スクロール・バーにかぶってたら、マウスカーソルを消す */
mos_rdpos(NULL, &mx,&my);
if (mx > BAR_X - 16 && my > BAR_Y-16 && my < BAR_Y+BAR_SIZ+4)
MOS_disp(MOS_OFF);
/* スクロール・バーの差分だけを描く */
if ((bar_pos - last_pos) < 0)
{
DSP_putBlock(BAR_X,BAR_Y+3+bar_pos+bar_siz+1,
20,last_pos-bar_pos-1, vol_ptn);
if (last_pos - bar_pos > bar_siz)
last_pos = bar_pos + bar_siz;
pbox(BAR_X+2,BAR_Y+3+bar_pos,
BAR_X+18,BAR_Y+3+last_pos, 15,15);
}
else
{
DSP_putBlock(BAR_X,BAR_Y+3+last_pos,
20,bar_pos-last_pos-1, vol_ptn);
if (bar_pos - last_pos > bar_siz)
last_pos = bar_pos - bar_siz;
pbox(BAR_X+2,BAR_Y+3+last_pos+bar_siz,
BAR_X+18,BAR_Y+3+bar_pos+bar_siz, 15,15);
}
}
last_pos = bar_pos;
MOS_disp(MOS_ON);
}
static void set_wide_screen(int flag)
{
if ((wide = flag) == TRUE)
MOS_horizon(MIN_HORIZON, (max_horizon = MAX_HORIZON));
else
MOS_horizon(MIN_HORIZON, (max_horizon = MAX_HORIZON2));
MOS_vertical(MIN_VERTICAL, MAX_VERTICAL);
wide_screen(wide);
}
/* 右クリック時の動作 */
static void RIGHT_click(void)
{
set_wide_screen(!wide);
DSP_scr_bar(FALSE);
}
static void MENU_clip( REGS evt_t *ep, int x, int y, int sw )
{
static int lastev = -1 ;
static int repcount = 0 ;
auto int now ;
x = x, y = y, sw = sw ; /* 意味なし。ワーニングを避けるため */
now = ep->now ;
switch( now )
{
case Ev_CLIP_MOS:
mos_ptn( MOSCSR_HAND ) ;
if( !isclip( ep ) )
DSP_clip_on( ep ) ;
if( isrepeat( ep ) )
{
menu_event = ep->no ;
ep->now = Ev_REP_MOS ;
}
break ;
case Ev_REP_MOS:
if( lastev != Ev_REP_MOS )
repcount = 0 ;
else if( (++repcount) > 300 )
menu_event = ep->no, repcount = 0 ;
break ;
case Ev_DOLACK_MOS:
ep->now = Ev_NON ;
case Ev_MOVE_MOS:
if( !isclip( ep ) )
DSP_clip_off( ep ) ;
case Ev_OFF_MOS:
mos_ptn( MOSCSR_FINGER ) ;
break ;
case Ev_SELECT_MOS:
if( !isrepeat( ep ) )
menu_event = ep->no ;
if( !isclip( ep ) )
DSP_clip_off( ep ) ;
ep->now = Ev_ON_MOS ;
case Ev_ON_MOS:
mos_ptn( MOSCSR_HAND ) ;
break ;
}
lastev = now ;
}
/*
* タイトル部分を退避する
*/
void title_backup(int sw)
{
static char buf[TITLE_Y_SIZ*640/2];
MOS_disp(MOS_OFF);
if (sw == ON)
DSP_getBlock(X_DOTOFS,TITLE_Y_MIN, 639,TITLE_Y_MAX, buf);
else
DSP_putBlock(X_DOTOFS,TITLE_Y_MIN, 639,TITLE_Y_MAX, buf);
MOS_disp(MOS_ON);
}
/* テキスト表示状態のメニュー描画と、イベント登録 */
static void dsp_menu( void )
{
EVT_reset() ;
/* 上のラインの表示 */
dsp_box( X_DOTOFS,TITLE_Y_MIN, 639+X_DOTOFS,TITLE_Y_MAX,
BOX1_COL,BOX2_COL,WIND_COL ) ;
/* Version & Edition の表示 */
dsp_box( 270,5, 370,25, BLACK_l,BLACK_l,WIND_COL ) ;
*tmp = '\0';
_strcats(80, tmp, "BOOK v", version, NULL);
wrt(tmp, 280,8, BLACK_l,WIND_COL, 16);
EVT_set_node(270,5, 100,20, 128,MENU_clip,MEv_DOSCMD, CLIP|REP);
/* 表示書式 */
BTN_set( CR_X,CR_Y, 46,BSIZE2, WIND_COL, 128,MENU_clip,MEv_FORM, NOP ) ;
wrt("書式", CR_X+8,CR_Y+2, STD_COL,WIND_COL, 16);
/* 文字列検索 */
BTN_set( SR_X,SR_Y, 46,BSIZE2, WIND_COL, 128,MENU_clip,MEv_SEARCH, NOP ) ;
wrt( "検索", SR_X+8,SR_Y+2, STD_COL,WIND_COL, 16 ) ;
/* ファイル名 */
BTN_set( FNAM_X,FNAM_Y, 12*8+8,BSIZE2,
WIND_COL, 128,MENU_clip,MEv_FULLPATH, REP ) ;
wrt( now_file->name, FNAM_X+4+(12-strlen(now_file->name))*4,
FNAM_Y+2, STD_COL,WIND_COL, 16 ) ;
/* [音]ボタンの表示 */
if( can_use_snd == TRUE )
{
BTN_set( SND_X,SND_Y, 22,20, WIND_COL, 128,MENU_clip,MEv_SND, NOP ) ;
DSP_ptnColor( SND_X+2,SND_Y+2, 31,31, ptn_snd, 1 ) ;
}
/* [FS] ボタンの表示 */
BTN_set( FS_X,FS_Y, 28,27, WIND_COL, 128,MENU_clip,MEv_FS, NOP ) ;
DSP_ptnColor( FS_X,FS_Y, 31,31, ptn_file, 1 ) ;
/* [EXIT] ボタンの表示 */
BTN_set( EXIT_X,EXIT_Y, 28,27, WIND_COL, 128,MENU_clip,MEv_EXIT, NOP ) ;
DSP_ptnColor( EXIT_X,EXIT_Y, 31,31, ptn_door, 1 ) ;
/* 右側のスクロール・バー表示 */
dsp_box( HUP_X-2,HUP_Y-2, DOWN_X+BSIZE2+2, DOWN_Y+BSIZE2+2,
BOX1_COL,BOX2_COL,WIND_COL);
EVT_set_node(BAR_X+1,BAR_Y+3, 19,BAR_SIZ, 128,MOVE_clip,MEv_DUMMY, NOP);
BTN_set( HUP_X,HUP_Y, BSIZE2,BSIZE2-3, WIND_COL,
128,MENU_clip,MEv_vDOWN, REP);
wrt( "▲", HUP_X+2,HUP_Y+2+6, STD_COL,WIND_COL,8 ) ;
wrt( "▲", HUP_X+2,HUP_Y+2, STD_COL,WIND_COL,8 ) ;
BTN_set( HDOWN_X,HDOWN_Y, BSIZE2,BSIZE2-3, WIND_COL,
128,MENU_clip,MEv_vUP, REP);
wrt( "▼", HDOWN_X+2,HDOWN_Y+2, STD_COL,WIND_COL,8);
wrt( "▼", HDOWN_X+2,HDOWN_Y+2+6, STD_COL,WIND_COL,8);
BTN_set( UP_X,UP_Y, BSIZE2,BSIZE2-1, WIND_COL,
128,MENU_clip,MEv_mDOWN, REP ) ;
wrt( "▲", UP_X+2,UP_Y+2, STD_COL,WIND_COL,16 ) ;
BTN_set( DOWN_X,DOWN_Y, BSIZE2,BSIZE2-1, WIND_COL,
128,MENU_clip,MEv_mUP, REP ) ;
wrt( "▼", DOWN_X+2,DOWN_Y+1, STD_COL,WIND_COL,16 ) ;
/* 最大行数 */
/* sprintf( tmp, " 0/%d", now_file->line_max-1 ) ; */
strcpy( tmp, " 0/" ) ;
strcat( tmp, formdigitL( now_file->line_max-1, 6, NO ) ) ;
wrt( tmp, LNUM_X,LNUM_Y, STD_COL,WIND_COL, 16 ) ;
DSP_scr_bar(TRUE); /* スクロール・バーの表示 */
EVT_set_cancel(127, RIGHT_click); /* 右クリック */
EVT_set_node(S_XMIN,S_YMIN, S_XSIZ,S_YSIZ, /* 画面を掴む */
129,SCREEN_clip,MEv_DUMMY, LOCK);
}
/* 画面をテキスト表示状態にする */
static void set_screen(int mos_disp)
{
MOS_disp(MOS_OFF);
mos_backup(ON);
MOS_writePage(1);
set_wide_screen(wide); /* 横幅を設定 */
mos_backup(OFF);
EGB_displayPage( gwork, 1, 3 ) ; /* 両ページを表示 */
MOS_disp( mos_disp ) ;
}
/* 画面をテキスト表示状態にする */
static void set_text_screen(int lnum)
{
MOS_disp( MOS_OFF ) ;
cls( 0, 8 ) ;
cls( 1, 0 ) ;
set_screen( MOS_OFF ) ;
dsp_menu();
dsp_file(lnum);
redisp_lnum();
DSP_scr_bar(FALSE);
mos_ptn( MOSCSR_FINGER ) ;
MOS_disp( MOS_ON ) ;
}
/* ファイルセレクタ画面にする */
static void set_fs_screen( void )
{
MOS_disp(MOS_OFF);
set_wide_screen(OFF); /* 横幅を復元 */
cls(1, 0); /* 画面消去 */
cls(0, 0);
unset_auto_scroll(); /* 自動スクロール停止 */
vram_ofs = 0;
dsp_adr_set(0);
EGB_displayPage(gwork, 1, 3); /* 両ページを表示 */
}
static HEADER *read_file( char *file, readtype_t reform, int lnum )
{
/* 画面の準備 */
void prt_center(char *str, int y)
{
int siz;
siz = strlen(str) * 4 + 16;
pbox(320-siz,y, 320+siz, y+39, WIND_COL,WIND_COL);
wrt(str, 320-siz+16,y+12, STD_COL,WIND_COL, 16);
}
DSP_writePage(gwork, 1);
MOS_disp(MOS_OFF);
if (reform == FILE_READ)
{
set_screen(MOS_OFF);
/* EGB_displayPage(gwork, 1, 0); */ /* 両ページを非表示 */
cls(1, 0);
cls(0, 8);
prt_center(file, 150);
prt_center("ファイルを読み込んでいます", 230);
/*EGB_displayPage(gwork, 1, 3); */ /* 両ページを表示 */
}
else
prt_center("しばらくお待ちください", 220);
mos_ptn(MOSCSR_CLOCK);
MOS_disp(MOS_ON);
/* 実際の読み込み処理をやってもらう */
if ((now_file = read_sub(file, reform)) == NULL)
return NULL;
/* 画面の準備 */
set_text_screen(lnum);
return now_file;
}
int redisp_lnum(void)
{
#define COLUMN 6
static char buf[COLUMN+1];
static int last = 0;
int i, mx, my;
int number = now_file->line_num;
if ((auto_move != 0 || kb_check()) && abs(last-number) < 10)
return FALSE;
last = number;
buf[COLUMN] = '\0';
for (i = COLUMN-1; i >= 0; i--)
{
buf[i] = '0' + (number % 10);
if ((number /= 10) == 0)
break;
}
while (--i >= 0)
buf[i] = ' ';
mos_rdpos(NULL, &mx,&my);
if (mx > LNUM_X-16 && mx < LNUM_X+(COLUMN*8) &&
my > LNUM_Y-16 && my < LNUM_Y+16)
MOS_disp(MOS_OFF);
wrt(buf, LNUM_X,LNUM_Y, STD_COL,WIND_COL,16);
MOS_disp(MOS_ON);
return TRUE;
}
static void display_fullpathlist(char *file)
{
int num;
evt_t *ep;
int org_ctrl = setup.disp_ctrl;
int org_tab = setup.tabsiz;
/* msg[0] = "フルパス表示"; */
msg[0] = "フルパス\x95\x5C示";
msg[1] = "環境再初期化";
msg[2] = "About...";
msg[3] = NULL;
ep = EVT_get_node(128, MEv_FULLPATH);
num = select_drag(ep, TRUE, ep->x1,28, 160, msg, "");
DSP_clip_off(ep = EVT_get_node(128, MEv_FULLPATH));
ep->now = Ev_NON;
switch(num)
{
case 0: /* フルパス表示 */
{
static int xc = 0, yc = 0; /* position */
msg[0] = file;
msg[1] = NULL;
btn[0] = "確 認";
btn[1] = NULL;
select_mode(" 現在ファイル ", msg, btn, 26, &xc,&yc);
}
break;
case 1: /* BOOK.CFG再読み込み */
excmd_init();
wc_init();
configuration(config);
if (org_ctrl != setup.disp_ctrl || org_tab != setup.tabsiz)
read_file(file, FILE_REFORM, now_file->line_num);
init_screen();
set_text_screen(now_file->line_num);
break;
case 2: /* バージョン表示 */
{
static int xc = MENU_CENTERING, yc = 0; /* position */
msg[0] = "High Speed Text Viewer for FM-TOWNS";
msg[1] = "presented by MIYAZAKI & sugi 1990-93";
*tmp = '\0';
_strcats(80, tmp, "version ", _version, " ", date, NULL);
msg[2] = tmp;
msg[3] = NULL;
btn[0] = "確 認";
btn[1] = NULL;
select_mode(" <<< ひみつのBook >>> ", msg, btn, 28, &xc, &yc);
break;
}
}
}
int findstr( char *a, char *str, int len, int pos, int max )
{
int ch = tolower( *str ) ;
a += pos ;
if (setup.caps) /* 大小文字区別 */
{
for( ; max-- > 0 ; a++, pos++ )
if( *a == *str && memcmp( a, str, len ) == 0 )
return pos ;
}
else
{
for( ; max-- > 0 ; a++, pos++ )
if( tolower( *a ) == ch && jmemicmp( a, str, len ) == 0 )
return pos ;
}
return -1 ;
}
int findrstr( char *a, char *str, int len, int pos, int max )
{
int ch = tolower( *str ) ;
if( pos >= max )
pos = max - 1 ;
a += pos ;
if (setup.caps) /* 大小文字区別 */
{
for( ; pos >= 0 ; a--, pos-- )
if( *a == *str && memcmp( a, str, len ) == 0 )
return pos ;
}
else
{
for( ; pos >= 0 ; a--, pos-- )
if( tolower( *a ) == ch && jmemicmp( a, str, len ) == 0 )
return pos ;
}
return -1 ;
}
int get_nowline( void ) /* 外部ファイルに現在の表示開始行を通知する */
{
return now_file->line_num ;
}
/* 行内のバイト位置から、文字位置を計算する */
int calc_pos( char *str, int pos )
{
int cnt = 0 ;
while( pos-- > 0 )
{
if( *str < 0x20 ) /* 制御コード */
{
if( *str == '\x0D' && *(str+1) == '\x0A' ) /* 改行コード */
break ;
else if( *str == '\t' && setup.tabsiz > 0 ) /* タブ */
cnt += setup.tabsiz - ( cnt % setup.tabsiz ) ;
else if (setup.disp_ctrl) /* 一般制御コード */
cnt += 2 ;
else
cnt++ ;
}
else /* その他の文字 */
cnt++ ;
str++ ;
}
return cnt ;
}
/* 行内のバイト位置・表示開始位置・文字列長から表示桁数を計算する */
int calc_len( char *str, int pos, int xpos, int len )
{
int cnt = 0 ;
str += pos ;
while( len-- > 0 )
{
if( *str < 0x20 ) /* 制御コード */
{
if( *str == '\x0D' && *(str+1) == '\x0A' ) /* 改行コード */
cnt++, str++, len-- ;
else if( *str == '\t' && setup.tabsiz > 0 ) /* タブ */
cnt += setup.tabsiz - ( (xpos+cnt) % setup.tabsiz ) ;
else if( *str == '\x0A' && pos > 0 && *(str-1) == '\x0D' )
cnt++ ; /* 0x0A から検索した時 */
else if (setup.disp_ctrl) /* 一般制御コード */
cnt += 2 ;
else
cnt++ ;
}
else /* その他の文字 */
cnt++ ;
str++ ;
}
return cnt ;
}
static void search_str( void )
{
void line( int x, int y, int xs )
{
int X( x ) { return x > XMAX ? XMAX : x ; }
DSP_writePage( gwork, 0 ) ;
EGB_writeMode( gwork, MODE_XOR ) ;
dsp_box_clip( XMIN,y, XMAX,y, 2,2,2 ) ;
dsp_box_clip( XMIN,y+16, XMAX,y+16, 2,2,2 ) ;
dsp_box_clip( x,y+1,X(x+xs-1),y+15, 2,2,2 ) ;
y += dot->font ;
if( x+xs-1 > XMAX ) /* 2行に渡っている */
dsp_box_clip( XMIN,y, x+xs-1-XMAX+XMIN,y+16, 2,2,2 ) ;
DSP_writePage( gwork, 1 ) ;
EGB_writeMode( gwork, MODE_PSET ) ;
}
void cnv_str( char *str, int len )
{
char *p, tmpbuf[80] ;
int i ;
/* 制御文字を一般バイナリ形式から特殊表現形式に変換する */
for( i=0, p=tmpbuf ; i < len ; p++, i++ )
{
if( str[i] < 0x20 )
*p = CTRL_PRE, *++p = 0x40 | str[i] ;
else
*p = str[i] ;
}
*p = '\0' ;
strcpy( str, tmpbuf ) ;
}
int recnv_str( char *str )
{
char *p, tmpbuf[80] ;
int len ;
/* 制御文字を特殊表現形式から一般バイナリ形式に変換する */
for( len=0, p=str ; *p ; p++, len++ )
{
if( *p == CTRL_PRE )
tmpbuf[len] = *++p - 0x40 ;
else
tmpbuf[len] = *p ;
}
memcpy( str, tmpbuf, len ) ;
return len ;
}
static char str[50] = "" ;
static int str_len = 0 ;
static int menu_x = 600, menu_y = 0 ;
char laststr[50] = "" ;
char type[82] ; /* ANK, 漢字1/2byte識別 */
LINPTR *lp = NULL ;
int diff = 0, lnum=0 ;
int line_lnum=0, minline=0, maxline=0 /*, line_lineofs */;
int size_x, size_y ;
int x=0, xs=0, y=0, pos=0, forward ;
int newline = TRUE, found = FALSE ;
int lastcaps = setup.caps ;
mevt_t func, lastfunc = MEv_NULL;
HEADER *hd = now_file ;
while( 1 )
{
do {
cnv_str(str, str_len); /* 一般バイナリ形式→特殊表現形式 */
func = input_string(str, NO, &menu_x,&menu_y, &size_x,&size_y,
&minline,&maxline);
str_len = recnv_str(str); /* 特殊表現形式→一般バイナリ形式 */
} while (func != MEv_CANCEL && str_len == 0);
if( found == TRUE &&
minline >= line_lnum-dot->max_y+1 && maxline-1 <= line_lnum )
line(x, y, xs);
if (func == MEv_CANCEL)
break;
if (func == MEv_FfSEARCH || func == MEv_ErSEARCH)
{
if (func != lastfunc)
{
newline = TRUE;
if (func == MEv_FfSEARCH) /* ファイルの先頭から進む */
pos = lnum = 0;
else if (func == MEv_ErSEARCH) /* ファイルの末端から戻る */
pos = LINEMAX-1, lnum = hd->line_max - 1;
}
}
else if (((lnum < 1 || lnum > hd->line_max-1) &&
(memcmp(laststr, str, str_len) != 0 ||
func != lastfunc || lastcaps != setup.caps)) ||
(found == TRUE && (hd->line_num > line_lnum ||
hd->line_num < line_lnum-dot->max_y+2)))
{
newline = TRUE;
if (func == MEv_fSEARCH) /* 進む */
{
pos = 0 ;
lnum = hd->line_num + 1 ;
if( offset > 8 )
lnum++ ;
}
else /* 戻る */
{
pos = LINEMAX-1 ;
lnum = hd->line_num + dot->max_y - 2 ;
if (lnum > hd->line_max-1)
lnum = hd->line_max-1;
if( offset < -8 )
lnum-- ;
}
memcpy( laststr, str, str_len ) ;
}
else if( lastfunc != func && found == TRUE )
{ /* 途中で方向だけが変わった */
if( func == MEv_fSEARCH ) /* ↓方向 */
pos += 2 ;
else /* ↑方向 */
pos -= str_len+1 ;
}
mos_ptn(MOSCSR_CLOCK); /* 時計 */
lastcaps = setup.caps;
lastfunc = func;
forward = (func == MEv_fSEARCH || func == MEv_FfSEARCH) ? TRUE:FALSE;
found = FALSE;
memcpy(laststr, str, str_len);
while (TRUE)
{
if (pos < 0 || pos >= LINEMAX) /* 範囲検査 */
{
pos = forward ? 0 : LINEMAX-1 ;
if (forward) /* 進む */
lnum++;
else /* 戻る */
lnum--;
newline = TRUE;
}
if (lnum < 0 || lnum > hd->line_max-1)
break;
if (newline)
lp = &(base[lnum/LINEPTRs]->ptr[lnum%LINEPTRs]);
if (forward)
pos = findstr(lp->buf, str,str_len, pos, lp->bytes-pos);
else
pos = findrstr(lp->buf, str,str_len, pos, lp->bytes);
/* 発見できない */
if (pos < 0 || pos >= LINEMAX)
continue;
/* 発見した */
if (newline)
typecheck(type, lp->buf, lp->bytes), newline = FALSE;
if (type[pos] == IS_KANJI2) /* 漢字2バイト目 */
{
pos += forward ? 1:-1;
continue;
}
diff = lnum - hd->line_num;
if (lnum <= hd->line_max-1 &&
(diff < 1 || diff > dot->max_y-3 ||
offset != 0 && (diff == 1)))
{
dsp_file(lnum-10 < 0 ? 0 : lnum-10);
redisp_lnum();
DSP_scr_bar(FALSE);
}
if (offset != 0 && (lnum == 1 || lnum == hd->line_max-1))
dsp_adr_set(vram_ofs + (offset = 0));
x = calc_pos(lp->buf, pos);
xs = calc_len(lp->buf, pos, x, str_len);
x = x*8 + XMIN, xs *= 8;
y = (lnum - hd->line_num ) * dot->font + dot->ofs;
line(x, y+vram_ofs, xs);
line_lnum = lnum/*, line_lineofs = lnum - hd->line_num + 1 */;
if (x >= menu_x && x <= menu_x+size_x &&
y >= menu_y && y <= menu_y+size_y)
{
if (y > 240) menu_y = 0;
else menu_y = 480;
input_string(str, YES, &menu_x,&menu_y, &size_x,&size_y,
&minline,&maxline);
}
y += vram_ofs;
found = TRUE;
newline = FALSE;
pos += forward ? str_len : -1;
break;
}
/* みつからない */
if( lnum < 0 || lnum > hd->line_max-1 )
{
DSP_writePage( gwork, 0 ) ;
setup.palette.text.color = 8 ;
setup.palette.back.color = 10 ;
EGB_palette( gwork, 1, (char *)&setup.palette ) ;
int i ;
for( i = 0 ; i < 80_000 ; i++ ) ;
setup.palette.text.color = 10 ;
setup.palette.back.color = 8 ;
EGB_palette( gwork, 1, (char *)&setup.palette ) ;
DSP_writePage( gwork, 1 ) ;
}
}
}
u_char char_to_sc[] = {
0x1E, /* A */ 0x2E, /* B */ 0x2C, /* C */ 0x20, /* D */
0x13, /* E */ 0x21, /* F */ 0x22, /* G */ 0x23, /* H */
0x18, /* I */ 0x24, /* J */ 0x25, /* K */ 0x26, /* L */
0x30, /* M */ 0x2F, /* N */ 0x19, /* O */ 0x1A, /* P */
0x11, /* Q */ 0x14, /* R */ 0x1F, /* S */ 0x15, /* T */
0x17, /* U */ 0x2D, /* V */ 0x12, /* W */ 0x16, /* Y */
0x2B, /* X */ 0x2A, /* Z */ };
u_char sc_to_char[] = {
' ',' ','1','2','3','4','5','6','7','8','9','0','-','^','\\',' ',
' ','Q','W','E','R','T','Y','U','I','O','P','@','[',' ','A','S',
'D','F','G','H','J','K','L',';',':',']','Z','X','C','V','B','N',
'M',',','.','/','"' };
static keytbl_t text_key[] = {
{0xFF5D, MEv_FULLPATH }, /* PF1 : メニュー */
{0xFF5E, MEv_FORM }, /* PF2 : 書式 */
{0xFF5F, MEv_SEARCH }, /* PF3 : 検索 */
{0xFF60, MEv_DOSCMD }, /* PF4 : 外部コマンド */
{0xFF66, MEv_SND }, /* PF10 : SND */
{0xFF69, MEv_FS }, /* PF11 : FS */
{0xFF5B, MEv_EXIT }, /* PF12 : EXIT */
{0xFF11, MEv_EXIT }, /* 'Q' : EXIT */
{0xFF01, MEv_EXIT }, /* ESC : EXIT */
{0xFF21, MEv_SEARCH }, /* 'F' : 検索 */
{0xFF2D, MEv_DISPCR }, /* 'V' : 改行文字表示切り換え */
{0xFF12, MEv_GOTO_TOP }, /* 'W' : テキスト先頭へ移動 */
{0xFF2A, MEv_GOTO_BTM }, /* 'Z' : テキスト末尾へ移動 */
{ 0x013, MEv_sDOWN }, /* 'E': 逆スクロール */
{ 0x113, MEv_mDOWN }, /* S+'E': 中速逆スクロール */
{ 0x213, MEv_hDOWN }, /* C+'E': 高速逆スクロール */
{ 0x313, MEv_hDOWN }, /* SC+'E': 高速逆スクロール */
{ 0x02B, MEv_sUP }, /* 'X': スクロール */
{ 0x12B, MEv_mUP }, /* S+'X': 中速 スクロール */
{ 0x22B, MEv_hUP }, /* C+'X': 高速 スクロール */
{ 0x32B, MEv_hUP }, /* SC+'X': 高速 スクロール */
{ 0x04F, MEv_mDOWN }, /* ← : 中速逆スクロール */
{ 0x14F, MEv_hDOWN }, /* S+← : 高速逆スクロール */
{ 0x24F, MEv_hDOWN }, /* C+← : 高速逆スクロール */
{ 0x34F, MEv_hDOWN }, /* SC+← : 高速逆スクロール */
{ 0x04D, MEv_sDOWN }, /* ↑ : 逆スクロール */
{ 0x14D, MEv_mDOWN }, /* S+↑ : 中速逆スクロール */
{ 0x24D, MEv_hDOWN }, /* C+↑ : 高速逆スクロール */
{ 0x34D, MEv_hDOWN }, /* SC+↑ : 高速逆スクロール */
{ 0x051, MEv_mUP }, /* → : 中速 スクロール */
{ 0x151, MEv_hUP }, /* S+→ : 高速 スクロール */
{ 0x251, MEv_hUP }, /* C+→ : 高速 スクロール */
{ 0x351, MEv_hUP }, /* SC+→ : 高速 スクロール */
{ 0x050, MEv_sUP }, /* ↓ : スクロール */
{ 0x150, MEv_mUP }, /* S+↓ : 中速 スクロール */
{ 0x250, MEv_hUP }, /* C+↓ : 高速 スクロール */
{ 0x350, MEv_hUP }, /* SC+↓ : 高速 スクロール */
{0xFF6E, MEv_uDOWN }, /* 前行 : 超高速逆スクロール */
{0xFF70, MEv_uUP }, /* 次行 : 超高速 スクロール */
{0xFF73, MEv_WIDTH }, /* 実行 : 画面幅の切り換え */
{ -1, MEv_NULL }, /* キーイベント定義おしまい */
};
mevt_t key_event(int keycode, keytbl_t *kp)
{
int mask, key;
if (keycode < 1)
return MEv_NULL;
while (kp->key > 0) /* キーアドレスは1以上 */
{
if ((key = kp->key) & 0xF000) /* mask ? */
{
mask = (key >> 4) & 0xF00;
key &= 0xFFF;
}
else
mask = 0;
if (key == (keycode | mask))
return kp->event;
kp++;
}
return MEv_NULL;
}
/* メインループと、その補助サブルーチン */
/*
* ファイルセレクタでファイルを選択する
*
* この関数から脱出するには、
* 1. キャンセル可能状態でキャンセルが選択される
* 2. 終了が選択される
* 3. ファイルが選択され、そのファイルを読み込むことができた
* このいずれかの状態になったときだけである。
*
* 関数の戻り値は、この3つの状態を返す
* また、ファイルが選択され、読み込みに成功した場合は、渡されたバッファに
* パスリストを設定する
*
* in
* int enable_cancel : TRUE -> キャンセル可能
* FALSE -> キャンセル不可能
* char path[] : 選択されたファイルのパスリストが格納される
*
* out
* -1 : 終了
* 0 : キャンセル
* 1 : 選択
*/
int fs(int enable_cancel, char *path)
{
char *file;
while (1)
{
set_fs_screen(); /* 画面をセットアップ */
file = file_select(enable_cancel); /* ファイルを選択 */
if (file == NULL) /* EXIT: 終了 */
return -1;
if (*file == '\0') /* ESC: 取消 */
{ /* キャンセル可能でなければ選べない */
return 0;
}
else /* ファイル選択 */
{
if (read_file(file, FILE_READ, 0) != NULL) /* 読み込み成功 */
{
strncpy(path, file, 254);
return 1;
}
}
}
}
void _dsp_main(char *pathlist)
{
const lines = 2; /* 高速スクロール時のスクロール行数 */
int i, ch, value;
HEADER *hd = now_file;
mevt_t repeat_evt = MEv_NULL;
mevt_t keyon = MEv_NULL;
int new_cr = setup.disp_cr;
int new_ctrl = setup.disp_ctrl;
int new_tab = setup.tabsiz;
int new_dpl = setup.dpl_mode;
int now_offset = offset;
set_wide_screen(OFF); /* 横幅は拡大せず */
set_screen(MOS_ON);
while (1) /* テキスト表示状態のメイン・ループ */
{
/* 行番号の表示 */
redisp_lnum();
/* イベント発生待ち */
for (i = 0, menu_event = repeat_evt;
menu_event == MEv_NULL;
EVT_loop(127, 129), i++)
{
if (i > 256)
{
if ((ch = kb_check()) != 0)
{
menu_event = key_event(ch, text_key);
}
if (keyon != MEv_NULL &&
(auto_move == 0 || menu_event != keyon))
{ /* キーから手を離していたら */
unset_auto_scroll(); /* 自動スクロール停止 */
keyon = MEv_NULL;
}
i = 0;
redisp_lnum(); /* 行番号の表示 */
}
}
repeat_evt = MEv_NULL;
/* イベント処理 */
switch (menu_event) {
case MEv_FS: /* [FS] ボタン */
switch (fs(TRUE, pathlist)) {
case -1: /* 終了 */
return;
case 0: /* キャンセル */
set_text_screen(hd->line_num);
break;
case 1: /* ファイル読み込み */
hd = now_file;
break;
}
break;
case MEv_EXIT: /* [EXIT] ボタン */
if (check_exit() == 1)
return;
break;
case MEv_SND: /* [音] ボタン */
snd_scrn();
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
break;
case MEv_vDOWN: /* 加速度のつく 上矢印 */
value = auto_move;
if (value == 0)
value = - setup.btn_speed;
else if ((value -= 1) == 0)
value -= 1;
set_auto_scroll(value); /* 自動スクロール開始 */
break;
case MEv_vUP: /* 加速度のつく 下矢印 */
if (value == 0)
value = setup.btn_speed;
else if ((value += 1) == 0)
value += 1;
set_auto_scroll(value); /* 自動スクロール開始 */
break;
case MEv_FORM: /* 表示書式の変更 */
new_cr = setup.disp_cr;
new_ctrl = setup.disp_ctrl;
new_tab = setup.tabsiz;
new_dpl = setup.dpl_mode;
now_offset = offset;
select_form(&new_cr, &new_tab, &new_dpl, &new_ctrl);
if (new_tab != setup.tabsiz || new_ctrl != setup.disp_ctrl)
{ /* タブか制御文字の処理が変更されたら */
setup.tabsiz = new_tab ; /* ファイルのリフォームをおこなう */
setup.disp_ctrl = new_ctrl ;
hd = read_file(pathlist, FILE_REFORM, hd->line_num);
}
if (new_dpl != setup.dpl_mode || new_cr != setup.disp_cr)
{ /* 行間隔か改行モードが変更されたら、再表示 */
setup.disp_cr = new_cr;
setup.dpl_mode = new_dpl;
dot = &dots[setup.dpl_mode];
now_offset = offset;
dsp_file(hd->line_num);
vertical_screen(dot->lines);
DSP_scr_bar(TRUE);
offset = now_offset;
}
break;
case MEv_DISPCR: /* 改行表示の切り換え */
setup.disp_cr = !setup.disp_cr;
now_offset = offset;
dsp_file(hd->line_num);
offset = now_offset;
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
break;
case MEv_FULLPATH: /* フルパスリスト表示 */
display_fullpathlist(pathlist);
break;
case MEv_SEARCH: /* 文字列検索 */
unset_auto_scroll(); /* 自動スクロール停止 */
search_str();
break;
case MEv_DOSCMD: /* 外部コマンド */
if (excmd_num == 0)
break;
int xsiz;
char *msg[EXCMD_MAX+1];
char keytbl[EXCMD_MAX+1];
for (i = 0; i < excmd_num; i++)
{
if ((msg[i] = malloc(excmd_len+1)) == NULL)
break;
strcpy(msg[i], formstrL(excmd[i].name, excmd_len));
if (*excmd[i].name >= 'A' && *excmd[i].name <= 'Z')
keytbl[i] = char_to_sc[*excmd[i].name-'A'];
else
keytbl[i] = '\xFF';
}
keytbl[i] = '\0';
msg[i] = NULL;
if ((xsiz = excmd_len * 8 + 16) < 100)
xsiz = 100;
xsiz = select_drag(EVT_get_node(128, MEv_DOSCMD), TRUE,
270,28, xsiz, msg, keytbl);
for (i = 0; i < excmd_num; i++)
if (msg[i] != NULL)
free(msg[i]);
if (xsiz >= 0 && exec_cmd(xsiz))
set_text_screen(hd->line_num);
break;
case MEv_WIDTH: /* 画面幅の変更 */
RIGHT_click(); /* 右クリック時と同じイベント */
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
break;
case MEv_GOTO_TOP: /* テキスト先頭へ移動 */
case MEv_GOTO_BTM: /* テキスト末尾へ移動 */
unset_auto_scroll(); /* 自動スクロール停止 */
offset = 0;
dsp_adr_set(vram_ofs);
if (menu_event == MEv_GOTO_TOP)
i = 0;
else if (menu_event == MEv_GOTO_BTM)
if ((i = hd->line_max - dot->max_y + 1) < 0)
i = 0;
dsp_file(i);
while (kb_check() != 0) ; /* キーから手を離すまで待つ */
break;
case MEv_sDOWN: /* キーボードによる低速スクロール */
case MEv_mDOWN: /* キーボードによる中速スクロール */
case MEv_hDOWN: /* キーボードによる高速スクロール */
if (keyon != menu_event)
{
value = setup.btn_speed;
switch (menu_event) {
case MEv_mDOWN: value *= 2; break;
case MEv_hDOWN: value *= 4; break;
}
set_auto_scroll(-value); /* 自動スクロール開始 */
keyon = menu_event;
}
break;
case MEv_sUP: /* キーボードによる低速スクロール */
case MEv_mUP: /* キーボードによる中速スクロール */
case MEv_hUP: /* キーボードによる高速スクロール */
if (keyon != menu_event)
{
value = setup.btn_speed;
switch (menu_event) {
case MEv_mUP: value *= 2; break;
case MEv_hUP: value *= 4; break;
}
set_auto_scroll(value); /* 自動スクロール開始 */
keyon = menu_event;
}
break;
case MEv_uUP: /* キーボードによる超高速スクロール */
case MEv_uDOWN: /* キーボードによる超高速スクロール */
if (auto_move != 0)
unset_auto_scroll(); /* 自動スクロール停止 */
if (offset != 0) {
offset = 0;
dsp_adr_set(vram_ofs);
}
if (menu_event == MEv_uUP) {
i = hd->line_now + (dot->max_y - hd->cur_pos - 1) + lines;
if (i >= hd->line_max)
i = hd->line_max;
} else {
if ((i = hd->line_num - lines) < 0)
i = 0;
}
dsp_scrn(i);
if (key_event(kb_check(), text_key) == menu_event)
repeat_evt = menu_event;
break;
}
}
}
void dsp_main(char *file)
{
char pathlist[256];
dot = &dots[setup.dpl_mode];
if (file != NULL)
strcpy(pathlist, file);
else
pathlist[0] = '\0';
if (file == NULL || read_file(file, FILE_READ, 0) == NULL)
if (fs(FALSE, pathlist) == -1) /* 終了 */
return;
_dsp_main(pathlist);
unset_auto_scroll(); /* 自動スクロール停止 */
free_head();
cls(1, 0);
cls(0, 0);
set_fs_screen();
}